import { computed, onMounted, ref } from 'vue';
import { defineStore } from 'pinia';
import { LOGIN_WITH_EMAIL, LOGIN_WITH_PHONE, LOGIN_WITH_WECHAT } from '@/constants/auth';
import { RouteMap, useRouter } from '@/router';
import { isWechat } from '@/utils/platform';
import * as AuthService from '../api/auth';
import { useUserStore } from './user';
import { merge } from 'lodash-es';

/**
 * 登录模式
 */
export type LoginMode =
  | typeof LOGIN_WITH_PHONE
  | typeof LOGIN_WITH_EMAIL
  | typeof LOGIN_WITH_WECHAT;

export const useAuthStore = defineStore('auth', () => {
  const token = ref<string>('');
  const authId = ref<string>('');

  const referrer = ref<number>(0);
  const privacyText = ref<string>('');

  const router = useRouter();
  const userStore = useUserStore();

  const isLoggedIn = computed(() => {
    return !!token.value;
  });

  async function SetprivacyText() {
    const config = await AuthService.GetAppConfig({});
    // 请求接口获取信息
    privacyText.value = config.data.appPrivacy;
  }

  function GetprivacyText() {
    return privacyText.value;
  }

  function Setreferrer(referrer_id: number) {
    referrer.value = referrer_id;
  }

  async function checkAuthState() {
    const r1 = await uni.login({ provider: 'weixin' });
    const { code, data } = await AuthService.checkAuthState(r1.code);
    if (code === 0) {
      token.value = data.token;
      authId.value = data.authId;
      uni.setStorageSync('token', data.token);
    }
    if (token.value) {
      userStore.getUserInfo();
    }
  }

  const isAgreementAccepted = ref(false);

  function toggleAgreementAccepted() {
    isAgreementAccepted.value = !isAgreementAccepted.value;
  }

  const loginForm = ref({
    phoneNumber: '',
    countryPrefix: '+86',
    countryName: '中国',
    email: '',
    verificationCode: ''
  });

  function setEmail(email: string) {
    loginForm.value.email = email;
  }

  function setPhoneNumber(phoneNumber: string) {
    loginForm.value.phoneNumber = phoneNumber;
  }

  function setCountryPrefix(countryPrefix: string, countryName: string) {
    loginForm.value.countryPrefix = countryPrefix;
    loginForm.value.countryName = countryName;
    router.back();
  }

  function setVerificationCode(verificationCode: string) {
    loginForm.value.verificationCode = verificationCode;
  }

  const isSent = ref(false);
  const retrySeconds = ref(60);

  function countdown() {
    setTimeout(() => {
      if (retrySeconds.value === 0) {
        isSent.value = false;
        retrySeconds.value = 60;
      } else {
        retrySeconds.value -= 1;
        countdown();
      }
    }, 1000);
  }

  async function sendVerificationCode() {
    let res;

    if (isPhoneMode.value) {
      res = await AuthService.sendPhoneCode(
        loginForm.value.phoneNumber,
        loginForm.value.countryPrefix
      );
    }

    if (isEmailMode.value) {
      res = await AuthService.sendEmailCode(loginForm.value.email);
    }

    if (res.code === 0) {
      isSent.value = true;
      countdown();
    }
  }

  async function loginWithVerificationCode() {
    const data = {
      code: loginForm.value.verificationCode,
      referrer: referrer.value
    };

    if (isPhoneMode.value) {
      merge(data, {
        login_type: 'phone',
        source: isWechat() ? 'WX_MINI' : 'H5',
        phone: loginForm.value.phoneNumber,
        area_no: loginForm.value.countryPrefix
      });
    }

    if (isEmailMode.value) {
      merge(data, {
        login_type: 'email',
        source: 'H5',
        email: loginForm.value.email
      });
    }

    const r1 = await AuthService.PhoneLogin(data);
    if (r1.code === 0) {
      token.value = r1.data.token;
      uni.setStorageSync('token', r1.data.token);
      if (r1.data.isNewMember) {
        router.to(RouteMap.joinUser);
      } else {
        await userStore.getUserInfo();
        router.back();
      }
    }
  }

  async function loginWithWechatBoundPhone(phoneCode: string) {
    const r1 = await AuthService.decryptPhoneNumber(phoneCode);
    const r2 = await AuthService.bindPhoneNumber({
      bindType: 'WX_MINI',
      authId: authId.value,
      phone: r1.data.phoneNumber,
      area_no: '+' + r1.data.countryCode,
      source: 'WX_MINI',
      referrer: referrer.value,
      code: '999999'
    });
    if (r2.code === 0) {
      token.value = r2.data.token;
      uni.setStorageSync('token', r2.data.token);
      if (r2.data.isNewMember) {
        router.to(RouteMap.joinUser);
      } else {
        await userStore.getUserInfo();
        router.back();
      }
    }
  }

  async function logout() {
    token.value = '';
    uni.removeStorageSync('token');
  }

  async function WxLoginGetOpenId(code: string) {
    uni.login({
      provider: 'weixin',
      onlyAuthorize: true,
      success: async function (event) {
        const WxLogin = await AuthService.checkAuthState(event.code);
        authId.value = WxLogin.data?.authId;
        if (!WxLogin.data.isBind) {
          loginWithWechatBoundPhone(code);
        } else {
          token.value = WxLogin.data.token;
          uni.setStorageSync('token', WxLogin.data.token);
          await userStore.getUserInfo();
          router.back();
        }
      }
    });
  }

  function CheckToken() {
    let tokenStorage = uni.getStorageSync('token');
    if (tokenStorage !== undefined || tokenStorage != '') {
      token.value = tokenStorage;
      userStore.getUserInfo();
    }
  }

  const mode = ref<LoginMode>(isWechat() ? LOGIN_WITH_WECHAT : LOGIN_WITH_PHONE);
  const isPhoneMode = computed(() => mode.value === LOGIN_WITH_PHONE);
  const isEmailMode = computed(() => mode.value === LOGIN_WITH_EMAIL);
  const isWechatMode = computed(() => mode.value === LOGIN_WITH_WECHAT);

  /**
   * 设置登录模式为一键登录（微信绑定手机号登录）
   */
  function setModeToWechat() {
    // 将state的值更新为微信绑定手机号登录模式
    mode.value = LOGIN_WITH_WECHAT;
  }

  /**
   * 设置登录模式为手机号登录
   */
  function setModeToPhone() {
    mode.value = LOGIN_WITH_PHONE;
  }

  /**
   * 设置登录模式为邮箱登录
   */
  function setModeToEmail() {
    mode.value = LOGIN_WITH_EMAIL;
  }

  return {
    isAgreementAccepted,
    toggleAgreementAccepted,
    loginForm,
    setEmail,
    setPhoneNumber,
    setCountryPrefix,
    setVerificationCode,
    isSent,
    retrySeconds,
    sendVerificationCode,
    isLoggedIn,
    checkAuthState,
    loginWithVerificationCode,
    loginWithWechatBoundPhone,
    logout,
    WxLoginGetOpenId,
    CheckToken,
    Setreferrer,
    GetprivacyText,
    SetprivacyText,
    isPhoneMode,
    isEmailMode,
    isWechatMode,
    setModeToPhone,
    setModeToEmail,
    setModeToWechat
  };
});
